
AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
include( 'shared.lua' )
util.PrecacheSound( "explode_9" )
util.PrecacheSound( "ambient/levels/labs/electric_explosion4.wav" )
util.PrecacheSound( "ambient/levels/labs/electric_explosion3.wav" )
util.PrecacheSound( "ambient/levels/labs/electric_explosion1.wav" )
util.PrecacheSound( "ambient/explosions/exp2.wav" )
util.PrecacheSound( "k_lab.ambient_powergenerators" )
util.PrecacheSound( "ambient/machines/thumper_startup1.wav" )
util.PrecacheSound( "coast.siren_citizen" )
util.PrecacheSound( "common/warning.wav" )

function ENT:Initialize()

	self.Entity:SetName("Shockwave Warhead")
	self.Entity:SetModel( "models/items/combine_rifle_ammo01.mdl" )

	local phys = self.Entity:GetPhysicsObject()
	if (phys:IsValid()) then
		phys:Wake()
		phys:EnableGravity(false)
		phys:EnableDrag(false)
		phys:EnableCollisions(false)
	end

	self.PhysObj = self.Entity:GetPhysicsObject()
	self.STime = CurTime()
	self.BTime = self.STime + 3

	self.Entity:SetNetworkedFloat( "FireTime", CurTime() )
	
end

function ENT:PhysicsUpdate()

end


function ENT:SpawnFunction( ply, tr )

	if ( !tr.Hit ) then return end

	local SpawnPos = tr.HitPos + tr.HitNormal * 36

	local ent = ents.Create( "fusionbomb_head" )
	ent:SetPos( SpawnPos )
	ent:Spawn()
	ent:Activate()
	return ent
end

function ENT:Think()
	self.Entity:SetColor(0,0,0,1)
	
	if (CurTime() >= self.BTime && self.Blasted != true) then
		self.Blasted = true
		local effectdata = EffectData()
		effectdata:SetMagnitude( 1 )
		
		local Pos = self.Entity:GetPos()
	
		effectdata:SetOrigin( Pos )
		effectdata:SetScale( 23000 )
		util.Effect( "warpcore_breach", effectdata )
		local tAllPlayers = player.GetAll()
		for _, pPlayer in pairs( tAllPlayers ) do
			pPlayer.Entity:EmitSound( "explode_9" )
		end
		self:EmitSound( "explode_9" )
		
		local blastradius = 3000
		
		for _,Ent in pairs( constraint.GetAllConstrainedEntities( self.Entity ) ) do
			if Ent != self.Entity then
				if (string.find(Ent.Entity:GetClass(),"prop") ~= nil) then
					local delay = (math.random(300, 700) / 100)
					Ent.Entity:SetSolid( SOLID_NONE ) --we don't need to be crunching the phys collisions too
					Ent.Entity:DrawShadow( false )
					Ent.Entity:SetKeyValue("exploderadius","1")
					Ent.Entity:SetKeyValue("explodedamage","1")
					Ent.Entity:Fire("break","",tostring(delay))
					Ent.Entity:Fire("kill","",tostring(delay + 1))
					Ent.Entity:Fire("enablemotion","",0) --bye bye fort that took you 4 hours to make
					constraint.RemoveAll( Ent.Entity )
				else
					if (Ent.Entity:IsValid()) then
						Ent.Entity:Remove()
					end
				end
			
			end
		end
		

		for key,found in pairs(ents.FindInSphere(Pos,blastradius)) do
			movetype = 	found:GetMoveType()
			if (movetype == 2 or movetype == 3 or movetype == 5 or movetype == 6 or movetype == 8 or movetype == 9) then
				local entpos = found:LocalToWorld(found:OBBCenter()) --more accurate than getpos
				local vecang = entpos - Pos
				if vecang.z < 0 then vecang.z = 0 end
				vecang:Normalize()
			
				if found:IsNPC() then --ugh, messy
					util.BlastDamage(self.Entity, self:GetPlayer(), found:GetPos(), 256, 512)
				elseif found:IsPlayer() then
					found:SetModel("models/player/charple01.mdl")
					util.BlastDamage(self.Entity, self:GetPlayer(), found:GetPos(), 256, 512)
				elseif found:IsValid() then
					
					local physobj = found:GetPhysicsObject()
					local mass = 1
					if(physobj:IsValid()) then
						mass = physobj:GetMass();
					end
					
					if (found:GetMoveType() ~= 6) or not physobj:IsValid() then --if it's not a physics object...
						found:SetVelocity(vecang*(170*mass)) --push it away
					elseif (string.find(found:GetClass(),"ragdoll") ~= nil) then --if it's a ragdoll...
						physobj:ApplyForceCenter(vecang*(8e4*mass)) --push it away anyway :D
					else -- if it is a physics object...
						physobj:ApplyForceOffset(vecang*(8e4*mass),entpos + Vector(math.random(-20,20),math.random(-20,20),math.random(20,40))) --still push it away
					end
					
					util.BlastDamage(self.Entity, self:GetPlayer(), Pos - vecang*64, 384, 1000) --splode it
				end
			end
		end
		
		local shake = ents.Create("env_shake")
		shake:SetKeyValue("amplitude", "16")
		shake:SetKeyValue("duration", "6")
		shake:SetKeyValue("radius", 1) 
		shake:SetKeyValue("spawnflags", 5) 
		shake:SetKeyValue("frequency", "240")
		shake:SetPos(Pos)
		shake:Spawn()
		shake:Fire("StartShake","","0.6")
		shake:Fire("kill","","8")

		local damage = ents.Create("point_hurt")
		damage:SetKeyValue("DamageRadius", 3000)
		damage:SetKeyValue("Damage" , 1000)
		damage:SetKeyValue("DamageDelay", 3)
		damage:SetKeyValue("DamageType" ,"67108864")
		damage:SetPos(tracer.HitPos)
		damage:Fire("TurnOn" , "", 0)
		damage:Fire("TurnOff" , "", 2)
		damage:Fire("kill","", 2)

	
		--shatter all glass
		for k,v in pairs(ents.FindByClass("func_breakable_surf")) do
			local dist = (v:GetPos() - Pos):Length()
			v:Fire("Shatter","",dist/19e3)
		end
		
		for k,v in pairs(ents.FindByClass("func_breakable")) do
			local dist = (v:GetPos() - Pos):Length()
			v:Fire("break","",dist/19e3)
		end
		self.Entity:Remove()
	end
end

function ENT:PhysicsCollide( data, physobj )
	
end

function ENT:OnTakeDamage( dmginfo )
	
end

function ENT:Use( activator, caller )

end